﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using LitJson;
using luck_draw.common;
using luck_draw.control;
using Microsoft.DirectX.AudioVideoPlayback;

namespace luck_draw
{
	/// <summary>
	/// MainWindow.xaml 的交互逻辑
	/// </summary>
	public partial class MainWindow : Window
	{
		// 存放格子的集合
		private List<DrawBtn> drawBtnList = new List<DrawBtn>(60);
		// 随机数
		Random r = new Random();
		// 能否使用抽奖
		private volatile bool canClick = true;
		// 背景音乐
		private Audio bgAudio;
		// 背景音乐播放索引
		private int bgMusicIndex = 0;
		public MainWindow()
		{
			InitializeComponent();
			big_image.Source = new BitmapImage(new Uri(Environment.CurrentDirectory + "/img/"+Config.BigPicName,UriKind.Absolute));
			bgAudio = new Audio("sound/"+Config.BgMusicList[bgMusicIndex++ % Config.BgMusicList.Count]);
			if(Config.StartBgMusic) bgAudio.Play();
			bgAudio.Ending += (sender, e) =>
			{
				bgAudio.Open("sound/" + Config.BgMusicList[bgMusicIndex++ % Config.BgMusicList.Count]);
				bgAudio.Play();
			};
			GemRotateAnimate();
		}

		/// <summary>
		/// 读取配置文件
		/// </summary>
		private void ReadConfig()
		{
			StreamReader sr = new StreamReader(Environment.CurrentDirectory + "/conf/conf.txt");
			string json = sr.ReadToEnd();
			sr.Close();
			JsonMapper.ToObject<Config>(json);
		}

		/// <summary>
		/// 窗体初始化事件，在构造方法执行完成前先执行
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void win_Initialized(object sender, EventArgs e)
		{
			ReadConfig();
			double left = 180, top = 20, span = 70;
			// 抽奖格索引
			int index = 0;
			// 图片索引分别为 电，火，水，草，土
			int[] powerImgIndex = {1, 1, 1, 1, 1};
			/**** 初始化各抽奖格子的位置 *********/

			// 第一部分
			for (int i = 0; i < 11; i++)
			{
				DrawBtn drawBtn = new DrawBtn()
				{
					Height = 60,
					Width = 60,
					Uid = index.ToString(),
					Background = new SolidColorBrush(Color.FromRgb(245, 245, 245)),
					Power = (PowerType)(index % powerImgIndex.Length),
					ImgSource = GetImgSourceByIndex(powerImgIndex, (PowerType)(index % powerImgIndex.Length)),
					Text = Config.PriceTexts[index]
				};
				canvas.Children.Add(drawBtn);
				Canvas.SetLeft(drawBtn,left);
				Canvas.SetTop(drawBtn,top);
				left += span;
				index += 1;
				drawBtnList.Add(drawBtn);
			}
			// 第二部分
			left -= span; top += span;
			for (int i = 0; i < 6; i++)
			{
				DrawBtn drawBtn = new DrawBtn()
				{
					Height = 60,
					Width = 60,
					Uid = index.ToString(),
					Background = new SolidColorBrush(Color.FromRgb(245, 245, 245)),
					Power = (PowerType)(index % powerImgIndex.Length),
					ImgSource = GetImgSourceByIndex(powerImgIndex, (PowerType)(index % powerImgIndex.Length)),
					Text = Config.PriceTexts[index]
				};
				canvas.Children.Add(drawBtn);
				Canvas.SetLeft(drawBtn, left);
				Canvas.SetTop(drawBtn, top);
				top += span;
				index += 1;
				drawBtnList.Add(drawBtn);
			}
			// 第三部分
			for (int i = 0; i < 11; i++)
			{
				DrawBtn drawBtn = new DrawBtn()
				{
					Height = 60,
					Width = 60,
					Uid = index.ToString(),
					Background = new SolidColorBrush(Color.FromRgb(245, 245, 245)),
					Power = (PowerType)(index % powerImgIndex.Length),
					ImgSource = GetImgSourceByIndex(powerImgIndex, (PowerType)(index % powerImgIndex.Length)),
					Text = Config.PriceTexts[index]
				};
				canvas.Children.Add(drawBtn);
				Canvas.SetLeft(drawBtn, left);
				Canvas.SetTop(drawBtn, top);
				left -= span;
				index += 1;
				drawBtnList.Add(drawBtn);
			}
			// 第四部分
			left += span; top -= span;
			for (int i = 0; i < 6; i++)
			{
				DrawBtn drawBtn = new DrawBtn()
				{
					Height = 60,
					Width = 60,
					Uid = index.ToString(),
					Background = new SolidColorBrush(Color.FromRgb(245, 245, 245)),
					Power = (PowerType)(index % powerImgIndex.Length),
					ImgSource = GetImgSourceByIndex(powerImgIndex, (PowerType)(index % powerImgIndex.Length)),
					Text = Config.PriceTexts[index]
				};
				canvas.Children.Add(drawBtn);
				Canvas.SetLeft(drawBtn, left);
				Canvas.SetTop(drawBtn, top);
				top -= span;
				index += 1;
				drawBtnList.Add(drawBtn);
			}
			// 内圈第一部分
			left += span; top += span;
			for (int i = 0; i < 9; i++)
			{
				DrawBtn drawBtn = new DrawBtn()
				{
					Height = 60,
					Width = 60,
					Uid = index.ToString(),
					Background = new SolidColorBrush(Color.FromRgb(245, 245, 245)),
					Power = (PowerType)(index % powerImgIndex.Length),
					ImgSource = GetImgSourceByIndex(powerImgIndex, (PowerType)(index % powerImgIndex.Length)),
					Text = Config.PriceTexts[index]
				};
				canvas.Children.Add(drawBtn);
				Canvas.SetLeft(drawBtn, left);
				Canvas.SetTop(drawBtn, top);
				left += span;
				index += 1;
				drawBtnList.Add(drawBtn);
			}
			// 内圈第二部分
			left -= span; top += span ;
			for (int i = 0; i < 4; i++)
			{
				DrawBtn drawBtn = new DrawBtn()
				{
					Height = 60,
					Width = 60,
					Uid = index.ToString(),
					Background = new SolidColorBrush(Color.FromRgb(245, 245, 245)),
					Power = (PowerType)(index % powerImgIndex.Length),
					ImgSource = GetImgSourceByIndex(powerImgIndex, (PowerType)(index % powerImgIndex.Length)),
					Text = Config.PriceTexts[index]
				};
				canvas.Children.Add(drawBtn);
				Canvas.SetLeft(drawBtn, left);
				Canvas.SetTop(drawBtn, top);
				top += span;
				index += 1;
				drawBtnList.Add(drawBtn);
			}
			// 内圈第三部分
			for (int i = 0; i < 9; i++)
			{
				DrawBtn drawBtn = new DrawBtn()
				{
					Height = 60,
					Width = 60,
					Uid = index.ToString(),
					Background = new SolidColorBrush(Color.FromRgb(245, 245, 245)),
					Power = (PowerType)(index % powerImgIndex.Length),
					ImgSource = GetImgSourceByIndex(powerImgIndex, (PowerType)(index % powerImgIndex.Length)),
					Text = Config.PriceTexts[index]
				};
				canvas.Children.Add(drawBtn);
				Canvas.SetLeft(drawBtn, left);
				Canvas.SetTop(drawBtn, top);
				left -= span;
				index += 1;
				drawBtnList.Add(drawBtn);
			}
			// 内圈第四部分
			left += span; top -= span;
			for (int i = 0; i < 4; i++)
			{
				DrawBtn drawBtn = new DrawBtn()
				{
					Height = 60,
					Width = 60,
					Uid = index.ToString(),
					Background = new SolidColorBrush(Color.FromRgb(245, 245, 245)),
					Power = (PowerType)(index % powerImgIndex.Length),
					ImgSource = GetImgSourceByIndex(powerImgIndex, (PowerType)(index % powerImgIndex.Length)),
					Text = Config.PriceTexts[index]
				};
				canvas.Children.Add(drawBtn);
				Canvas.SetLeft(drawBtn, left);
				Canvas.SetTop(drawBtn, top);
				top -= span;
				index += 1;
				drawBtnList.Add(drawBtn);
			}

			// 做一次全场动画
			Task.Run(async () =>
			{
				await Task.Delay(500);
				drawBtnList.ForEach(d =>
				{
					Dispatcher.Invoke(() => d.SelectedAnimate(100));
					Thread.Sleep(100);
				});
			});
		}

		public ImageSource GetImgSourceByIndex(int[] powerImgIndex, PowerType power)
		{
			StringBuilder filepath = new StringBuilder(Environment.CurrentDirectory + "/img");
			int powerIndex = (int) power;
			switch (power)
			{
				case PowerType.ELECTRIC:
					filepath.Append("/e/" + powerImgIndex[powerIndex] + ".png");
					break;
				case PowerType.FIRE:
					filepath.Append("/f/" + powerImgIndex[powerIndex] + ".png");
					break;
				case PowerType.WATER:
					filepath.Append("/w/" + powerImgIndex[powerIndex] + ".png");
					break;
				case PowerType.GRASS:
					filepath.Append("/g/" + powerImgIndex[powerIndex] + ".png");
					break;
				case PowerType.SOIL:
					filepath.Append("/s/" + powerImgIndex[powerIndex] + ".png");
					break;
			}

			powerImgIndex[powerIndex] += 1;
			return new BitmapImage(new Uri(filepath.ToString(),UriKind.Absolute));
		}

		/// <summary>
		/// 开始抽奖
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void start_luckDraw(object sender, MouseButtonEventArgs e)
		{
			if(!canClick) return;
			Image image = sender as Image;
			PowerType power = (PowerType) Convert.ToInt16(image?.Uid);
			RandomPrize(power);
		}

		/// <summary>
		/// 根据能量类型随机出奖品
		/// </summary>
		/// <param name="power"></param>
		private void RandomPrize(PowerType power)
		{
			List<DrawBtn> powerBtns = drawBtnList.Where(d => d.Power == power && d.IsOpen == false).ToList();
			int count = powerBtns?.Count ?? 0;
			if (count == 0)
			{
				MessageBox.Show("该类型的奖池已经没有了哦!");
			}
			else
			{
				DrawBtn drawBtn = powerBtns[r.Next(powerBtns.Count)];
				int index = Convert.ToInt16(drawBtn.Uid);
				PriceAnimate(index,power);
			}
		}

		/// <summary>
		/// 抽奖动画
		/// </summary>
		/// <param name="index"></param>
		/// <param name="power"></param>
		private void PriceAnimate(int index, PowerType power)
		{
			canClick = false;
			Task.Run(() =>
			{
				int i = (int)power;
				int time = Config.SelectTime;
				for (; i < drawBtnList.Count; i+= 5)
				{
					if (drawBtnList[i].IsOpen == false)
					{
						Dispatcher.Invoke(() => drawBtnList[i].SelectedAnimate(time));
						Thread.Sleep(time);
					}
				}
				for (i -= 5; i >= index && i >= 0 ; i -= 5)
				{
					if (drawBtnList[i].IsOpen == false)
					{
						Dispatcher.Invoke(() => drawBtnList[i].SelectedAnimate(time));
						Thread.Sleep(time);
						time = time >= 800 ? 800 : time + 50;
					}
				}

				Dispatcher.Invoke(() =>
				{
					drawBtnList[index].SelectCompleteAnimate(Config.CompleteRefreshTime, async(price) =>
					{
						canClick = true;
						if (drawBtnList.All(d => d.IsOpen))
						{
							await Task.Delay(Config.BigPicDelay);
							big_image.Visibility = Visibility.Visible;
						}
					});
				});
			});
		}

		/// <summary>
		/// 中心宝石旋转动画
		/// </summary>
		private async void GemRotateAnimate()
		{
			RotateTransform transform = new RotateTransform(0);
			double angle = 0, angle2 = 0;
			while (true)
			{
				transform.Angle = angle;
				btn_ele.RenderTransform = transform;
				btn_fire.RenderTransform = transform;
				btn_grass.RenderTransform = transform;
				btn_soil.RenderTransform = transform;
				btn_water.RenderTransform = transform;
				if (angle > 360) angle = 0;
				if (angle2 > 360) angle2 = 0;
				angle += 3; angle2 += 1;
				// canvas_center.RenderTransform = transform;
				// transform.Angle = angle2;
				await Task.Delay(1);
			}
		}

		/// <summary>
		/// 隐藏大图
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void big_image_MouseDown(object sender, MouseButtonEventArgs e)
		{
			// big_image.Visibility = Visibility.Hidden;
		}
	}
}
